home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / asm_n_z.zip / SCRNFLIP.ASM < prev    next >
Assembly Source File  |  1986-03-01  |  13KB  |  372 lines

  1. ; This program is described in BYTE, November 1983, Pages 99 - 116.
  2. ; Article is entitled "ENHANCING SCREEN DISPLAYS FOR THE IBM PC",
  3. ; author is Tim Field.
  4.  
  5. ; Define interrupt vectors for both keyboard interrupt 16H and screen
  6. ; interrupt 10H.  Both are in segment 0:
  7.  
  8. KEYVECT       SEGMENT    AT 0             ;Define KEYBOARD int. vector
  9.           ORG    16H*4
  10.           KEYINT    LABEL DWORD
  11. KEYVECT       ENDS
  12.  
  13. SCRVECT       SEGMENT    AT 0             ;Define SCREEN int. vector
  14.           ORG    10H*4
  15.           SCRINT    LABEL DWORD
  16. SCRVECT       ENDS
  17.  
  18. ; Define constants:
  19.  
  20.           BW_VAL         EQU  07H         ;Standard B&W attribute
  21.           EQUIP_FLAG     EQU  410H         ;RAM address of equipment stat
  22.           CHK_MODE         EQU  15         ;INT fn: Check screen mode
  23.           MONO_MODE      EQU  7         ;Mode 7 = monochrome monitor
  24.           COLOR_ADPT     EQU  3         ;Modes 0-3: non-graphics color
  25.  
  26. ; Start code area:
  27.  
  28. CODE          SEGMENT    PARA             ;Start code at offset 100H
  29.           ASSUME    CS:CODE          ;from starting segment; leaves
  30.           ORG    100H             ;room for PSP
  31. KEY          PROC    FAR
  32.  
  33. ; Initialization code - used only once during startup:
  34.  
  35. START:
  36.           JMP    INIT_CODE         ;Call initialization routine
  37.  
  38. ; Define storage areas and data structures:
  39. ; Define keystroke scan codes for the five SCREEN functions:
  40.  
  41.           FORE_INC         DW   5E00H      ;Foreground increment
  42.           BACK_INC         DW   6000H      ;Background increment
  43.           C80_40         DW   6200H      ;80x25 to 40x25 flip-flop key
  44.           COL_MON         DW   6400H      ;COLOR/MONO flip-flop key
  45.           REPAINT         DW   6600H      ;Repaint scrn using curr. mode
  46.           CUR_MODE         DW   COL80_AREA     ;Initialize starting mode
  47.           MONO_SET         DW   MONO_AREA     ;Pointer to monochrome area
  48.           COLOR_SET      DW   COL80_AREA     ;Pointer to active color area
  49.           SCRN_ATTR      DB   70H         ;Current screen attribute
  50.           SCRN_MODE      DB   255         ;Save current screen mode
  51.  
  52. ; Define structure used to contain information about 40 and 80 column color
  53. ; modes as well as monochrome mode:
  54.  
  55. S STRUC
  56.           CORNER         DW   0         ;Defines COL/ROW count of
  57.                          ;characters for the monitor
  58.           BF         DW   0         ;Colors of FORE and BACK
  59.           EQUIP         DW   0         ;Equipment setting
  60.           MODE         DW   0         ;AX value for setting the mode
  61. S ENDS                         ;of the monitor
  62.  
  63. ; Now set up three screen structures with default condition:
  64.  
  65.   COL80_AREA  S     <5019H,0107H,20H,3>     ;80x25 white FORE, blue BACK
  66.   COL40_AREA  S     <2819H,0107H,10H,1>     ;40x25 brown FORE, black BACK
  67.   MONO_AREA   S     <5019H,0007H,30H,7>     ;Monochrome, reverse video
  68.  
  69. KEY_CALL:     DB   0EAH              ;Far JMP address to KEYBOARD
  70.           DD   0                 ;interrupt.  See article
  71.  
  72. ; Procedure KEY_RTNE intercepts keyboard interrupt and determines if the
  73. ; keystroke is one of the five SCREEN ones:
  74.  
  75. KEY_RTNE:
  76.           STI                 ;Turn on interrupts
  77.           CMP    AH,0
  78.           JNE    KEY_CALL
  79.           PUSH    DS             ;Save registers
  80.           PUSH    BX
  81.           PUSH    CX
  82.           PUSH    DX
  83.           PUSH    ES
  84.           PUSH    DI
  85.           PUSH    CS             ;Point DS to CS segment by
  86.           POP    DS             ;PUSH / POP operation
  87.           ASSUME    DS:CODE
  88. INT_LOOP:                     ;IBM keyboard procedure
  89.           PUSHF                 ;expects an interrupt call
  90.           MOV    BX,OFFSET KEY_CALL+1     ;Address to ROM keyboard code
  91.           CALL    DWORD PTR [BX]         ;Call keyboard routine
  92.           MOV    BX,CUR_MODE         ;Get current mode address
  93.           CMP    AX,COL_MON         ;See if COLOR/MON flip flop
  94.           JNE    TEST_FORE         ;key.    Exit if not. Otherwise:
  95.           CMP    BX,MONO_SET         ;Flip flop screen mode
  96.           JE    SET_COLOR         ;If monochrome, swap to color
  97.           CMP    MONO_SET,0         ;See if monochrome installed
  98.           JE    NEXT_KEY         ;Ignore command if not
  99.           MOV    BX,MONO_SET         ;Otherwise set up monochrome
  100.           JMP    SHORT DO_CHG
  101. SET_COLOR:
  102.           CMP    COLOR_SET,0         ;See if COLOR monitor enabled
  103.           JE    NEXT_KEY         ;Skip if not
  104.           MOV    BX,COLOR_SET         ;Set up for color
  105. DO_CHG:
  106.           CALL    SCREEN_CHG         ;Implement screen change
  107. NEXT_KEY:
  108.           MOV    AH,0             ;Set up to fetch keystroke
  109.           JMP    INT_LOOP         ;Fetch next key input
  110. TEST_FORE:
  111.           PUSH    AX             ;Save registers
  112.           PUSH    BX             ;See if in GRAPHICS mode
  113.           MOV    AH,CHK_MODE
  114.           INT    10H
  115.           POP    BX             ;Restore BX register
  116.           CMP    AL,COLOR_ADPT         ;If between 0-3, not graphics
  117.           JLE    NOT_GRAPH
  118.           CMP    AL,MONO_MODE         ;Monochrome mode
  119.           JGE    NOT_GRAPH
  120.           POP    AX             ;Restore stack
  121.           JMP    DONE             ;If color-graphics mode, do
  122. NOT_GRAPH:                     ;not change modes
  123.           POP    AX             ;Restore AX
  124.           CMP    AX,FORE_INC         ;Increment FOREGROUND color?
  125.           JNE    TEST_BACK         ;Skip if not
  126.           CMP    BX,COLOR_SET         ;See if currently using color
  127.           JNE    BW_FLOP          ;If not, go deal with B&W
  128.           MOV    AX,[BX].BF         ;Gets BACK in AL, FORE in AH
  129. EQ_FORE:
  130.           INC    AL             ;Increment FOREGROUND color
  131.           AND    AL,7             ;Keep it within bounds
  132.           CMP    AL,AH             ;See if same as BACKGROUND
  133.           JE    EQ_FORE          ;Increment again if yes
  134.           MOV    [BX].BF,AX         ;Save back to structure
  135.           JMP    DO_CHG             ;Redraw the screen
  136. TEST_BACK:
  137.           CMP    AX,BACK_INC         ;Increment BACKGROUND color?
  138.           JNE    TEST_REPAINT         ;Skip if not
  139.           CMP    BX,COLOR_SET         ;See if currently using color
  140.           JNE    BW_FLOP          ;If not, go deal with B&W
  141.           MOV    AX,[BX].BF         ;Gets BACK in AL, FORE in AH
  142. EQ_BACK:
  143.           INC    AH             ;Increment BACKGROUND color
  144.           AND    AH,7             ;Keep it within bounds
  145.           CMP    AH,AL             ;See if same as FOREGROUND
  146.           JE    EQ_BACK          ;Increment again if yes
  147.           MOV    [BX].BF,AX         ;Save back to structure
  148.           JMP    DO_CHG             ;Redraw the screen
  149. BW_FLOP:                     ;Flip flop B&W monitor
  150.           MOV    AX,[BX].BF         ;BACK in AH, FORE in Al
  151.           XCHG    AH,AL             ;Swap FOREGROUND, BACKGROUND
  152.           MOV    [BX].BF,AX         ;Save back to structure
  153.           JMP    DO_CHG             ;Redraw the screen
  154. TEST_REPAINT:
  155.           CMP    AX,REPAINT         ;Repaint the screen?
  156.           JE    DO_CHG             ;If yes, then repaint screen
  157. TEST_80_40:
  158.           CMP    AX,C80_40         ;80-40 flip flop key?
  159.           JNE    DONE             ;Exit if not
  160.           CMP    BX,OFFSET COL40_AREA     ;Is curr. pointer area 40x25?
  161.           JNE    TST80             ;Skip if not
  162.           MOV    BX,OFFSET COL80_AREA     ;Otherwise, flip to 80x25
  163.           JMP    SHORT SAVE_COL         ;Save to COLOR_SET
  164. TST80:
  165.           CMP    BX,OFFSET COL80_AREA     ;Is current 80x25 color?
  166.           JNE    NEXT_KEY         ;Ignore key if not
  167.           MOV    BX,OFFSET COL40_AREA
  168. SAVE_COL:
  169.           MOV    COLOR_SET,BX         ;Save to COLOR_SET
  170.           JMP    SET_COLOR         ;Implement
  171. DONE:
  172.           POP    DI             ;Restore registers
  173.           POP    ES
  174.           POP    DX
  175.           POP    CX
  176.           POP    BX
  177.           POP    DS
  178.           IRET                 ;Return from interrupt
  179. KEY          ENDP                 ;End of main routine
  180.  
  181. ; This routine changes current monitor screen mode.  On input, BX points to
  182. ; the current monitor structure:
  183.  
  184. SCREEN_CHG    PROC    NEAR
  185.           MOV    AX,0             ;Get segment address for RAM
  186.           MOV    ES,AX             ;EQUIP_FLAG
  187.           MOV    AX,ES:EQUIP_FLAG     ;Get set of EQUIP flags
  188.           AND    AL,0CFH          ;Scrap current monitor flag
  189.           OR    AX,[BX].EQUIP         ;Set up new monitor flag
  190.           MOV    ES:EQUIP_FLAG,AX     ;Save back in RAM
  191.           MOV    CUR_MODE,BX         ;Indicate new mode
  192.  
  193. ; Now set up attribute for FOREGROUND and BACKGROUND:
  194.  
  195.           MOV    DX,[BX].BF         ;Get both FORE and BACK in DX
  196.           MOV    CL,4             ;Shift count
  197.           SHL    DH,CL             ;Shift BACK into upper nibble
  198.           OR    DH,DL             ;Move FORE into lower nibble
  199.           MOV    SCRN_ATTR,DH         ;Save results
  200.  
  201. ; See if we need to reset monitor (switching to new monitor?):
  202.  
  203.           MOV    AX,[BX].MODE         ;Get screen mode
  204.           CMP    AL,SCRN_MODE         ;Compare with current mode
  205.           JE    SET_ATTR         ;Skip if the same
  206.           MOV    SCRN_MODE,AL         ;Otherwise, save current mode
  207.           INT    10H             ;And reset to new monitor
  208. SET_ATTR:
  209.           CALL    CH_ATTR          ;Change attributes of current
  210.           RET                 ;screen
  211. SCREEN_CHG    ENDP
  212.  
  213. ; This routine repaints the active screen so that every character on the
  214. ; current screen is displayed with the new attributes.    On input, BX points
  215. ; to the current monitor structure:
  216.  
  217. CH_ATTR       PROC    NEAR
  218.  
  219. ; See if we need to redraw border for color mode
  220.  
  221.           CMP    BX,OFFSET MONO_SET     ;In color?
  222.           JE    NO_BORDER